package com.sdry.basic.service;

import com.sdry.basic.entity.AttendanceRecord;
import com.sdry.basic.entity.AttendanceTeam;
import com.sdry.basic.entity.AttendanceTeamType;
import com.sdry.basic.entity.AttendanceTeamUser;
import com.sdry.basic.mapper.AttendanceMapper;
import com.sdry.reportforms.entity.ZJPoint;
import com.sdry.system.entity.SysUser;
import com.sdry.untils.CoordinatesUtil;
import com.sdry.untils.DateUtil;
import com.sdry.untils.StringUtil;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author lian
 * @date 2020/04/13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AttendanceServiceImpl implements AttendanceService{

    @Resource
    private AttendanceMapper attendanceMapper;

    /**
     * 分页查询班组类型
     * @param  att 参数类型：班组类型实体 AttendanceTeamType
     * @return
     *  返回 null 表示没有找到
     */
    @Override
    public List<AttendanceTeamType> queryAttendanceType(AttendanceTeamType att) {
        return attendanceMapper.queryAttendanceType(att);
    }

    /**
     * 条件查询班组类型的数据有几条
     * @param  att 参数类型：班组类型实体 AttendanceTeamType
     * @return
     *  返回 null 表示没有找到
     */
    @Override
    public Long countAttendanceType(AttendanceTeamType att) {
        return attendanceMapper.countAttendanceType(att);
    }

    /**
     * 给班组类型表插入数据
     * @param  att 参数类型：班组类型实体 AttendanceTeamType
     * @return
     *  返回 正数 表示插入成功
     */
    @Override
    public Long insertAttendanceType(AttendanceTeamType att) {
        return attendanceMapper.insertAttendanceType(att);
    }

    /**
     * 修改班组类型表数据
     * @param  att 参数类型：班组类型实体 AttendanceTeamType
     * @return
     *  返回 正数 表示修改成功
     */
    @Override
    public Long updateAttendanceType(AttendanceTeamType att) {
        return attendanceMapper.updateAttendanceType(att);
    }

    /**
     * 删除班组类型表数据
     * @param  ids 主键ID用逗号（，）拼接的字符串
     * @return
     *  返回 正数 表示删除成功
     */
    @Override
    public Long deleteAttendanceType(String ids) {
        return attendanceMapper.deleteAttendanceType(ids);
    }

    /**
     * 查询所有班组
     * @return 返回 null 表示没有找到
     */
    @Override
    public List<AttendanceTeam> getTeamList() {
        return attendanceMapper.getTeamList();
    }

    /**
     * 查查询未绑定班组的用户
     * @param  user 用户类型实体：SysUser
     * @return 返回 null 表示没有找到
     */
    @Override
    public List<SysUser> queryUsersAreNotOnTheTeam(SysUser user) {
        return attendanceMapper.queryUsersAreNotOnTheTeam(user);
    }

    /**
     * 给班组用户表插入数据，返回ID
     * @param param 实体类
     * @return  返回正数，插入成功
     */
    @Override
    public Long insertAttendanceUser(AttendanceTeamUser param) {
        return attendanceMapper.insertAttendanceUser(param);
    }

    /**
     * 根据班组ID查询班组的成员
     * @return 返回null.没查到数据
     */
    @Override
    public List<SysUser> queryTeamMembers(Long teamId) {
        return attendanceMapper.queryTeamMembers(teamId);
    }

    /**
     * 根据主键拼接的字符串删除班组中的用户
     * @param ids 用户主键拼接的字符串
     * @return 返回正数，删除成功
     */
    @Override
    public Long deleteAttendanceTeamUser(String ids) {
        return attendanceMapper.deleteAttendanceTeamUser(ids);
    }

    /**
     * APP打卡功能
     * @param userId 用户ID
     * @param lat   打卡维度
     * @param lon   打卡经度
     * @param clockType 打卡状态（0：上班，1：下班）
     * @return  是否打卡成功
     */
    @Override
    public JSONObject appAttendanceClock(String userId, String lat, String lon, String clockType) {
        JSONObject jsonObject = new JSONObject();
        String status = "0";
        String message = "";
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //1、根据打卡人的ID查询班组规则，如果为空，则不用打卡
        List<AttendanceTeamType> teamTypes = attendanceMapper.getAttendanceTypeByUserId(userId);
        if(teamTypes.size() > 0){
            AttendanceTeamType team = teamTypes.get(0);
            String remark = null;
            //2、根据当前时间，判断是否在打卡时间内
            //当天的日期，格式（yyyy-MM-dd）
            String nowTime = DateUtil.dateFormat3();
            String nowDay = nowTime.substring(0,10);
            String nowHour = nowTime.substring(11,19);
            //当前日期的上一天
            String beforeDay = DateUtil.getTheDayBefore();
            //上班前开始打卡时间
            String startTime = team.getAttendanceClockTime();
            //上班时间
            String workTime = team.getAttendanceTime();
            //下班结束打卡时间
            String endTime = team.getClosingClockTime();
            //下班时间
            String closingTime = team.getClosingTime();
            Boolean flag = null;
            Integer type = StringUtil.isStr2Num(clockType) ? Integer.valueOf(clockType) : null;
            if(type != null){
                if(StringUtil.isNotEmpty(startTime) && StringUtil.isNotEmpty(workTime) && StringUtil.isNotEmpty(closingTime) && StringUtil.isNotEmpty(endTime)){
                    //2.1、如果是上班卡
                    if(type == 0){
                        //如果下班时间大于上班时间，就只算当天，否则下班时间要跨天
                        if(closingTime.compareTo(workTime) > 0){
                            //则打卡时间范围（上班打卡的开始时间~下班时间）
                            if(startTime.compareTo(nowHour) <= 0 && closingTime.compareTo(nowHour) >= 0){
                                flag = true;
                            }else{
                                flag = false;
                            }
                        }else{
                            //如果是跨天的班组
                            //则打卡时间范围（大于上班打卡的开始时间， 或者小于下班时间）
                            if(startTime.compareTo(nowHour) <= 0 || closingTime.compareTo(nowHour) >= 0){
                                flag = true;
                            }else{
                                flag = false;
                            }
                        }
                        //2.2、如果是下班卡
                    }else if(type == 1){
                        //则打卡时间范围（下班时间~结束下班打卡时间）
                        if(closingTime.compareTo(nowHour) <= 0 && endTime.compareTo(nowHour) >= 0){
                            flag = true;
                        }else{
                            flag = false;
                        }
                    }
                    //如果在打卡时间范围之内
                    if(flag){
                        //判断打卡地点
                        ZJPoint app = new ZJPoint();
                        app.setX(lon);
                        app.setY(lat);
                        ZJPoint actual = new ZJPoint();
                        actual.setX(team.getLon());
                        actual.setY(team.getLat());
                        boolean inCircle = CoordinatesUtil.isInCircle(app, actual, team.getToleranceRange());
                        if(inCircle){
                            //5、给考勤记录插入数据
                            AttendanceRecord ar = new AttendanceRecord();
                            ar.setUserId(Long.valueOf(userId));
                            ar.setClockLat(lat);
                            ar.setClockLon(lon);
                            ar.setClockTime(nowTime);
                            ar.setClockType(clockType.charAt(0));
                            //如果下班时间 > 上班时间, 则上下班在同一天，传参数：当前天
                            if(closingTime.compareTo(workTime) > 0){
                                ar.setRemark(nowDay);
                            }else{
                                //如果上下班时间跨天，且是下班打卡，传参数：当前天的上一天
                                if(type == 1){
                                    ar.setRemark(beforeDay);
                                    //如果上下班时间跨天，且是上班打卡，打卡时间小于下班时间（说明是凌晨24点之后打卡），传参数：当前天的上一天
                                }else if (type == 0 && closingTime.compareTo(nowHour) >= 0){
                                    ar.setRemark(beforeDay);
                                }else{
                                    ar.setRemark(nowDay);
                                }
                            }
                            Long result = attendanceMapper.queryLogByParam(ar);
                            if(result > 0){
                                status = "0";
                                message = "已经打卡，请勿重复打卡！";
                            }else{
                                Long id = attendanceMapper.insertAttendanceRecord(ar);
                                if(id > 0){
                                    status = "1";
                                    message = "打卡成功！";
                                }else{
                                    status = "0";
                                    message = "打卡失败，系统存储数据失败！";
                                }
                            }
                        }else{
                            status = "0";
                            message = "打卡失败，不能在规定的范围外打卡！";
                        }
                    }else{
                        status = "0";
                        message = "打卡失败，不能在规定的时间外打卡！";
                    }
                }else{
                    status = "0";
                    message = "打卡失败，班组信息不全！";
                }
            }else{
                status = "0";
                message = "数据丢失，请重新打卡！";
            }

        }else {
            status = "0";
            message = "打卡失败，该用户不在考勤组内！";
        }
        jsonObject.put("status", status);
        jsonObject.put("message", message);
        return jsonObject;
    }

}
